﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using Ro.AssistFunction.BackNodeInfo;
using Ro.AssistFunction.OutputManage;
using Ro.Common.RoArgs;
using Ro.Common.RoInterface.RoWebAction;
using Ro.Common.RoInterface.UserType;
using Ro.DriverEvent.FindElement;
using Ro.DriverEvent.IntegrationFun;

namespace Ro.DriverEvent.WebAction
{
    /// <summary>
    /// waituntil方法集
    /// todo 3-21 需要做方法混合的使用
    /// </summary>
    public class WebWaitUntil : IWebWaitUntilFunc
    {
        /// <summary>
        /// 等待页面载入完成
        /// </summary>
        /// <param name="sigNode">等待页面载入完成</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilPageIsLoaded(XmlNode sigNode)
        {
            //返回值
            WebActionResult back;
            try
            {
                IJavaScriptExecutor jsExecutor = RoTestObject.WebTestObject as IJavaScriptExecutor;
                string com = (string) jsExecutor?.ExecuteScript("return document.readyState");
                if (com == "complete")
                {
                    back = BackActionResult.BackWebResult(true, "未使用", "没有附加信息"); //结果
                }
                else
                {
                    back = BackActionResult.BackWebResult(false, "未使用", "等待页面停止刷新失败"); //结果
                }
            }
            catch (Exception e)
            {
                back = BackActionResult.BackWebResult(false, "未使用", "WebWaitUntilPageIsLoaded操作遭遇System异常"); //结果
                ExceptionOutPut.SystemExceptionOut("WebWaitUntilPageIsLoaded", e);
            }

            return back;
        }


        /// <summary>
        /// 验证是否包含
        /// </summary>
        /// <param name="sigNode">验证是否包含</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilStringContains(XmlNode sigNode)
        {
            //返回值
            WebActionResult back = new WebActionResult();
            ExtractNeedInfo extractNeedInfo = new ExtractNeedInfo();

            //实际类型
            string acttype = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "xsi:type");

            //提取超时
            TimeSpan timeout = extractNeedInfo.ExtractTimeout(sigNode);

            //提取元素
            string value = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "web:RoWebElementID");

            //预期值
            string expValue = extractNeedInfo.ExtractInnerText(sigNode, "web:ExpectedValue");

            //验证语言(允许某个控件显示多种不同的字符，只需包含即通过)
            List<string> langsList = new List<string>();

            //如果包含一个. 位符
            if (expValue.Contains("."))
            {
                SpecalArgsIntoValue specalArgsIntoValue = new SpecalArgsIntoValue();
                langsList = specalArgsIntoValue.BackLangsArgs(expValue);
            }
            else
            {
                //转换为正常的输入值
                ArgsIntoValue argsIntoValue = new ArgsIntoValue(expValue);
                expValue = argsIntoValue.BackValue;
            }

            //构造函数初始
            FindWebElement findElement = new FindWebElement(value, timeout);
            IWebElement ele = findElement.WebElement;
            try
            {
                //如果元素为空，反馈结果为空
                if (ele == null)
                {
                    back = BackActionResult.BackWebResult(false, value, "WebWaitUntilStringContains操作遭遇查找元素失败，获取元素为null"); //结果
                }
                else
                {
                    //循环实际值类型
                    string realactvalue;
                    switch (acttype)
                    {
                        case "web:Browser.Title":
                            realactvalue = RoTestObject.WebTestObject.Title;
                            if (realactvalue.Contains(expValue))
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证包含操作成功，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证包含操作失败，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }

                            break;
                        case "web:Browser.Url":
                            realactvalue = RoTestObject.WebTestObject.Url;
                            if (realactvalue.Contains(expValue))
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证包含操作成功，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证包含操作失败，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }
                            break;

                        case "web:RoWebElement.Text":


                            //如果是input控件
                            if (ele.TagName == "input")
                            {
                                //查找下一个同级节点
                                IWebElement temp = ele.FindElement(By.XPath("following-sibling::input"));
                                if (temp != null)
                                {
                                    //点击操作，相当于给定焦点
                                    Actions action = new Actions(RoTestObject.WebTestObject);
                                    action.Click(temp).Perform();
                                    realactvalue = temp.GetAttribute("value");
                                }
                                else
                                {
                                    realactvalue = ele.Text;
                                }
                            }
                            //等待验证的是非input控件
                            else
                            {
                                realactvalue = ele.Text;
                            }

                            //一般测试文本才会使用到langs
                            if (expValue.Contains("."))
                            {
                                string usevalue = (from temp in langsList where realactvalue.Contains(temp) select temp).SingleOrDefault();
                                if (usevalue != null)
                                {
                                    back = BackActionResult.BackWebResult(true, value, "验证包含操作成功，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                                }
                                else
                                {
                                    back = BackActionResult.BackWebResult(false, value, "验证包含操作失败，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                                }
                            }
                            else
                            {
                                if (realactvalue.Contains(expValue))
                                {
                                    back = BackActionResult.BackWebResult(true, value, "验证包含操作成功，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                                }
                                else
                                {
                                    back = BackActionResult.BackWebResult(false, value, "验证包含操作失败，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                                }
                            }

                            break;

                        case "web:RoWebElement.GetAttribute":
                            //提取元素
                            string attype = extractNeedInfo.ExtractAttributeValue(sigNode.LastChild, "web:Name");
                            realactvalue = ele.GetAttribute(attype);
                            if (realactvalue.Contains(expValue))
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证包含操作成功，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证包含操作失败，预期值：" + expValue + " 实际值：" + realactvalue); //结果
                            }
                            break;
                    }
                }
            }

            catch (Exception e)
            {
                back = BackActionResult.BackWebResult(false, value, "WebWaitUntilStringContains操作遭遇System异常"); //结果

                ExceptionOutPut.SystemExceptionOut("WebWaitUntilStringContains", e);
            }

            return back;
        }

        /*===================================================================================================================*/

        /// <summary>
        /// 验证是否相等
        /// </summary>
        /// <param name="sigNode">验证是否相等</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilAreEqual(XmlNode sigNode)
        {
            //返回值
            //初始化构造函数
            WebEqual webEqual = new WebEqual(sigNode);
            //返回结果
            WebActionResult back = webEqual.BackResult;

            return back;
        }

        /// <summary>
        /// 验证是否不等
        /// </summary>
        /// <param name="sigNode">验证是否不等</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilAreNotEqual(XmlNode sigNode)
        {
            //返回值
            //初始化构造函数
            WebEqual webEqual = new WebEqual(sigNode);
            //返回结果
            WebActionResult back = webEqual.BackResult;

            return back;
        }


        /*===================================================================================================================*/

        /// <summary>
        /// 验证是否为假
        /// </summary>
        /// <param name="sigNode">验证是否为假</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilIsFalse(XmlNode sigNode)
        {
            //返回值
            //初始化构造函数
            WebIs webEqual = new WebIs(sigNode);
            //返回结果
            WebActionResult back = webEqual.BackResult;

            return back;
        }

        /// <summary>
        /// 验证是否为真
        /// </summary>
        /// <param name="sigNode">验证是否为真</param>
        /// <returns>返回操作是否完成</returns>
        public WebActionResult WebWaitUntilIsTrue(XmlNode sigNode)
        {
            //返回值
            //初始化构造函数
            WebIs webEqual = new WebIs(sigNode);
            //返回结果
            WebActionResult back = webEqual.BackResult;

            return back;
        }

        /// <summary>
        /// 验证字符串最大长度
        /// </summary>
        /// <param name="sigNode">对应节点</param>
        /// <returns>返回操作</returns>
        public WebActionResult WebWaitUntilStringLength(XmlNode sigNode)
        {
            /*重新更改
             * 之前是直接通过验证同层节点，现在可以直接通过反馈获取xpath重新查找了
             */

            //返回值
            WebActionResult back = new WebActionResult();
            ExtractNeedInfo extractNeedInfo = new ExtractNeedInfo();
            //提取超时
            TimeSpan timeout = extractNeedInfo.ExtractTimeout(sigNode);

            //提取类型
            string usetype = extractNeedInfo.ExtractAttributeValue(sigNode.FirstChild, "web:Type");

            //提取长度
            int uselength = Convert.ToInt32(extractNeedInfo.ExtractAttributeValue(sigNode.FirstChild, "web:Length"));
            //提取控件
            string value = extractNeedInfo.ExtractAttributeValue(sigNode.FirstChild, "web:RoWebElementID");

            //构造函数初始化
            FindWebElement findElement = new FindWebElement(value, timeout);
            //元素自身
            IWebElement ele = findElement.WebElement;

            try
            {
                //如果元素为空，反馈结果为空
                if (ele == null)
                {
                    back = BackActionResult.BackWebResult(false, value, "WebWaitUntilStringLength操作遭遇查找元素失败，获取元素为null"); //结果
                }
                else
                {
                    //长度
                    IWebElement temp = ele.FindElement(By.XPath("following-sibling::input"));
                    //点击操作，相当于给定焦点
                    Actions action = new Actions(RoTestObject.WebTestObject);
                    action.Click(temp).Perform();
                    //获取长度
                    string b = temp.GetAttribute("value");
                    int textlength = b.Length;

                    //判断
                    switch (usetype)
                    {
                        case "Equal":

                            if (textlength == uselength)
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证字符串长度操作成功，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证字符串长度操作失败，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }

                            break;
                        case "Longer":

                            if (textlength > uselength)
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证字符串长度操作成功，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证字符串长度操作失败，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }

                            break;
                        case "Lower":

                            if (textlength < uselength)
                            {
                                back = BackActionResult.BackWebResult(true, value, "验证字符串长度操作成功，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }
                            else
                            {
                                back = BackActionResult.BackWebResult(false, value, "验证字符串长度操作失败，预期值：" + uselength + " 实际值：" + textlength); //结果
                            }
                            break;
                    }
                }
            }

            catch (Exception e)
            {
                back.Result = false;
                back.ControlId = value;
                back.ExtraInfo = "等待操作遭遇System异常";
                ExceptionOutPut.SystemExceptionOut("WebWaitUntilStringLength", e);
            }

            return back;
        }
    }
}